package com.bizmda.bizsip.source.client;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bizmda.bizsip.common.*;
import com.bizmda.bizsip.source.Source;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Method;

@Slf4j
public class BizServiceClientMethod {
    private final Method method;
    private final BizServiceClientProxy bizServiceClientProxy;

    private RestTemplate restTemplate = null;
    private Source source = null;

    public BizServiceClientMethod(Method method, BizServiceClientProxy bizServiceClientProxy) {
        this.method = method;
        this.bizServiceClientProxy = bizServiceClientProxy;
        if (this.restTemplate == null) {
            this.restTemplate = SpringUtil.getBean("restTemplate");
        }
        if (this.source == null) {
            this.source = SpringUtil.getBean("source");
        }
    }

    public Object execute(Object[] args) throws BizException {

//        final Annotation[] annotations = method.getAnnotations();
//        for (Annotation annotation : annotations) {
//            Class<? extends Annotation> aClass = annotation.annotationType();
////            if (aClass.equals(Insert.class)) {
////                System.out.println("execute insert {" + args[0] + "} completed");
////            }
////            if (aClass.equals(Update.class)) {
////                System.out.println("execute update {" + args[0] + "} completed");
////            }
//        }
        BizMessage<JSONObject> outMessage = this.doBizService(this.bizServiceClientProxy.getBizServiceId(), args);
        if (this.bizServiceClientProxy.getMapperInterface().equals(BizMessageInterface.class)) {
            return outMessage;
        }
        JSONObject jsonObject = new JSONObject(outMessage.getData());
        Object result = jsonObject.get("result");
        return BizUtils.methodReturnJSON2Bean(method,result);
//        if (result == null) {
//            return null;
//        }
//        if (result instanceof JSONObject) {
//            return JSONUtil.toBean((JSONObject) result, method.getReturnType());
//        } else if (result instanceof JSONArray) {
//            if (method.getReturnType() == List.class) {
//                return Convert.convert(method.getReturnType(), result);
//            }
//            JSONArray jsonArray = (JSONArray) result;
//            return jsonArray.toArray(method.getReturnType());
//        } else {
//            return Convert.convert(method.getReturnType(), result);
//        }
    }

    private BizMessage<JSONObject> doBizService(String bizServiceId, Object[] args) throws BizException {
        JSONObject jsonObject = new JSONObject();
        if (this.bizServiceClientProxy.getMapperInterface().equals(BizMessageInterface.class)) {
            if (args[0] instanceof JSONObject) {
                jsonObject = (JSONObject) args[0];
            } else {
                jsonObject = JSONUtil.parseObj(args[0]);
            }
        } else {
            jsonObject.set("className", bizServiceClientProxy.getMapperInterface().getName());
            jsonObject.set("methodName", this.method.getName());
            jsonObject.set("params", JSONUtil.parseArray(args));
            JSONObject parametersTypes = BizUtils.getParamtersTypesJSONObject(this.method,args);
            if (parametersTypes.size() > 0) {
                jsonObject.set("paramsTypes",parametersTypes);
            }
        }
        log.trace("调用App接口参数:\n{}",BizUtils.buildJsonLog(jsonObject));
        HttpHeaders header = new HttpHeaders();
        header.add("Biz-Service-Id", bizServiceId);
        HttpEntity<JSONObject> httpEntity = new HttpEntity<>(jsonObject, header);

        BizMessage<Object> outMessage = this.restTemplate.postForObject(this.source.getIntegratorUrl(), httpEntity, BizMessage.class);
        if (outMessage == null) {
            log.debug("Integrator返回为null");
            throw new BizException(BizResultEnum.SOURCE_RETURN_NULL);
        }
        if (outMessage.getCode() == 0) {
            log.debug("Integrator返回成功:{}", outMessage.getData());
        } else {
            log.debug("Integrator返回错误:{}-{}", outMessage.getCode(), outMessage.getMessage());
            throw new BizException(outMessage);
        }
        return BizMessage.buildSuccessMessage(outMessage, JSONUtil.parseObj(outMessage.getData()));
    }

}
